package ar.uba.fi.algo3.algoTank.Objetos.Tanques;

import java.io.Serializable;
import java.util.LinkedList;

import ar.uba.fi.algo3.algoTank.ObservadorJuego;
import ar.uba.fi.algo3.algoTank.Interfaces.Interactuable;
import ar.uba.fi.algo3.algoTank.Objetos.Objeto;
import ar.uba.fi.algo3.algoTank.Objetos.Posicion;
import ar.uba.fi.algo3.algoTank.Objetos.Proyectil;
import ar.uba.fi.algo3.algoTank.Objetos.Territorio;
import ar.uba.fi.algo3.algoTank.Objetos.Equipamiento.Arma;
import ar.uba.fi.algo3.algoTank.Objetos.Equipamiento.Armamento;

public class AlgoTank extends Tanque implements Interactuable, Serializable {

	private static final long serialVersionUID = 1L;
	//Comentario 
	private Armamento armamento;
	private LinkedList<TanqueEnemigo> observadores;
	private boolean disparando;
	
	public AlgoTank(){	
		super();
		//Inicializo el Armamento y establesco el Arma Actual
		this.armamento = new Armamento();
		this.observadores = new LinkedList<TanqueEnemigo>();
		this.frecuenciaDeDisparo = 4;
		this.disparando = false;
	}
	
	public AlgoTank(Posicion posicion,Territorio territorio){	
		super(posicion, territorio);
		//Inicializo el Armamento y establesco el Arma Actual
		this.armamento = new Armamento();
		this.observadores = new LinkedList<TanqueEnemigo>();
		this.frecuenciaDeDisparo = 4;
		this.disparando = false;
	}
	
	
	public void estaDisparando(boolean bool) {
		disparando = true;
	}
	
	public boolean estaDisparando(){
		return disparando;
	}
	
	
	public boolean esInteractuable() {
		return true;
	}
		
	public boolean interactuaConProyectil(){
		return true;
	}
	
	//si colisionan, entonces interactuan los objetos
	public boolean interactua(Objeto obj){
		return obj.colisiona(this);
	}	
	
	public void interactuar(Objeto obj){
			obj.interactuarConAlgoTank(this);
	}
		
	public Armamento getArmamento(){
		return this.armamento;
	}
	
	public void ActualizarArmaActual(){
		armaActual = this.armamento.getArmaActual();
	}
	
	
	public synchronized void addObservador(TanqueEnemigo tanque){
		observadores.add(tanque);
	}
	
	public synchronized void quitarObservador(TanqueEnemigo tanque){
		observadores.remove(tanque);
	}
	
	//informa el cambio de ubicacion a los observadores
	public void informarObservadores() {
		for (TanqueEnemigo tanque : observadores)
			tanque.setObjetivo(this.ubicacion);
	}
	
	public void vivir() {
		this.tiempoDesdeUltimoDisparo += deltaTiempo;
		if (estaDisparando())
			disparar();
		disparando = false;
	}
		
	public void mover(){
		this.calcularProximaUbicacion();
		
		//mueve el objeto
		if (territorio.ubicacionLibre(proximaUbicacion)) {
			this.setUbicacion(proximaUbicacion);
			informarObservadores();
		}
		
	}
	
	public void moverDerecha() {
		mirarDerecha();
		mover();
	}
	
	public void moverIzquierda() {
		mirarIzquierda();
		mover();
	}
	
	public void moverArriba() {
		mirarArriba();
		mover();
	}
	
	public void moverAbajo() {
		mirarAbajo();
		mover();
	}
	
	
	public void obtenerCanion(Arma arma, int municiones){
		this.armamento.agregarCanion(arma, municiones);
	}
	
	public void obtenerCohete(Arma arma, int municiones){
		this.armamento.agregarCohete(arma, municiones);
	}
	
	
	public void disparar() {
		if (puedeDisparar()) {
			this.ActualizarArmaActual();
			Proyectil nuevoProy = armaActual.disparar(this);
			nuevoProy.setTerritorio(territorio);
			nuevoProy.setDuenio(this);
			territorio.addObjeto(nuevoProy);
			nuevoProy.mover();
			nuevoProy.mover();
			armaActual.descontarMunicion(armamento);
			this.tiempoDesdeUltimoDisparo = 0;
			disparando=false;
			
		}
	}
	
	
	public void aumentarVidaEnPorciento(double porciento){	
		//Te aumenta la energia dependiendo el porciento ingresado por parametro
		float nuevaEnergia = this.getEnergia();
		nuevaEnergia += (float) ( this.getEnergia() * porciento ) /100; 
		this.setEnergia(nuevaEnergia);
	}
	
	public void aumentarVelocidadEnPorciento(double porciento){
		float velocidad = this.getMovimiento().getVelocidad();
		velocidad += (float) ( velocidad * porciento) /100 ;
		this.getMovimiento().setVelocidad(velocidad);
	}

	public void aumentarFrecuenciaDisparoEnPorciento(double porciento) {
		frecuenciaDeDisparo -= (frecuenciaDeDisparo*porciento) /100 ;
	}
	
	public void disminuirEnergiaEnPorciento(int porciento) {
		float energia = this.getEnergia();
		this.setEnergia(energia-(energia*porciento)/100);
	}
	
	public int CantidadMunicionesCanion(){
		return this.getArmamento().getMunicionesCanion(); 
	}

	public int CantidadMunicionesCohete() {
		return this.getArmamento().getMunicionesCohete(); 
	}
	
	public void avisarNuevoObjeto(ObservadorJuego obs) {
		obs.nuevoAlgoTank(this);
	}
	
}
